package com.infolab.aims.web;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.infolab.aims.GlobalConstant;
import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.CommonUtil;
import com.infolab.aims.common.InQueryHelper;
import com.infolab.aims.common.ParameterDateQueryHelper;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.common.exception.ResourceNotFoundException;
import com.infolab.aims.domain.Location;
import com.infolab.aims.domain.Section;
import com.infolab.aims.domain.SystemCodeType;
import com.infolab.aims.domain.SystemUser;
import com.infolab.aims.domain.asset.AssetComponent;
import com.infolab.aims.domain.asset.AssetModel;
import com.infolab.aims.domain.asset.AssetTransaction;
import com.infolab.aims.domain.asset.AssetTransactionItem;
import com.infolab.aims.service.intf.AssetModelService;
import com.infolab.aims.service.intf.AssetTransactionService;
import com.infolab.aims.service.intf.LocationService;
import com.infolab.aims.service.intf.SystemCodeService;
import com.infolab.aims.service.intf.SystemUserService;


@Controller
@RequestMapping("/issueOrder")
@SessionAttributes(value=IssueOrderController.SESSION_SEARCH_CRITERIA)
public class IssueOrderController extends AbstractController {

	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/issueOrder";
	public static final String JSP_MAIN_FORM="issueOrderForm";
	public static final String JSP_STOCK_TRANSFER="stockTransferForm";
	public static final String JSP_MAIN_SEARCH="issueOrderSearch";
	public static final String JSP_STOCK_SALES="stockSalesForm";

	@Autowired
	AssetTransactionService assetTransactionService;
	
	@Autowired
	SystemUserService systemUserService;
	
	@Autowired
	AssetModelService assetModelService;
	
	@Autowired
	SystemCodeService systemCodeService;
	
	@Autowired
	LocationService locationService;
	
	Log logger = LogFactory.getLog(getClass());

	@RequestMapping(value="createStockTransfer", method = RequestMethod.GET)
	public String createStockTransfer(Model model, HttpSession session, HttpServletRequest request) {
		AssetTransaction assetTransaction = new AssetTransaction();
		String typeValue = request.getParameter("assetTransactionType");
		assetTransaction.setAssetTransactionType(typeValue);
		List<Location> fromLocations = null;
		List<Location> toLocations = null;

		if(assetTransaction.isFaultyEquipmentTransfer() || assetTransaction.isInHouseTransfer()) {
			//find the WORKORDER_FAULT_LOCATION value
			SearchCriteria searchCriteria = new SearchCriteria();
			searchCriteria.addSearchCriteria("active", true);  
			searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_REPAIR_TRANSFER_LOCATION);
			SystemCodeType systemCodeType = systemCodeService.findSystemCodeType(searchCriteria);
			String [] ICWS = StringUtils.split(systemCodeType.getSystemCodeTypeValue(), ",") ;
	
			//make the in query
			InQueryHelper helper = new InQueryHelper("locationCode", Arrays.asList(ICWS));
			searchCriteria.addSearchCriteria("active", true);  
			searchCriteria.addSearchCriteria("locationCode", helper);
			fromLocations = locationService.searchLocationCriteria(searchCriteria);
			toLocations = fromLocations;
		}else{
			Section section = getCurrentSection(request);
			if(section==null) {
				fromLocations = (List<Location>)session.getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCATION);
				toLocations = fromLocations;
			}
			else
			{
				SearchCriteria searchCriteria = new SearchCriteria();
				searchCriteria.addSearchCriteria("sectionId", section.getSectionId());
				fromLocations = locationService.searchLocationCriteria(searchCriteria);
				searchCriteria = new SearchCriteria();
				toLocations = locationService.searchLocationCriteria(searchCriteria);
			}
		}
		assetTransaction.setAccessDepartment(getCurrentDepartment(request));
		model.addAttribute(assetTransaction);
		model.addAttribute("fromLocations", fromLocations);
		model.addAttribute("toLocations", toLocations);
		
		String target = JSP_STOCK_TRANSFER;
		if(typeValue.contains("SOI"))
			target = JSP_STOCK_SALES;
		return target;
	}
	

	@RequestMapping(value="create", method = RequestMethod.GET)
	public String createIssueOrder(Model model, HttpSession session,HttpServletRequest request) {

		AssetTransaction assetTransaction = new AssetTransaction();
		assetTransaction.setAccessDepartment(getCurrentDepartment(request));

		List<Location> fromLocations = getTheIssueLocation(session);
		List<Location> tmp = (List<Location>) request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCATION);
		
		
		List<Location> toLocations = new ArrayList<Location>();
		toLocations.addAll(tmp);
		toLocations.removeAll(fromLocations);
		
		model.addAttribute("fromLocations", fromLocations);
		model.addAttribute("toLocations", toLocations);
		
		model.addAttribute(assetTransaction);
		return JSP_MAIN_FORM;
	}

	@RequestMapping(value="createStockTransfer",method=RequestMethod.POST)
	public String saveStockTransfer(@ModelAttribute AssetTransaction assetTransaction, BindingResult result, Model model,HttpServletRequest request) {
		
		String successMsg = "";
		String type =  assetTransaction.getAssetTransactionType()!=null? (String)assetTransaction.getAssetTransactionType():"";
		String target = JSP_STOCK_TRANSFER;
		List<Location> fromLocations = new ArrayList<Location>();
		List<Location> toLocations = new ArrayList<Location>();
		populateLocations(fromLocations,toLocations,assetTransaction,request);
		
		
		
		if(type.contains(AssetTransaction.TRANSACTIONTYPE_SALESOFITEMS)){
			target = JSP_STOCK_SALES;
			successMsg = "Sales Of Items";
			assetTransaction.setAssetTransactionType(AssetTransaction.TRANSACTIONTYPE_SALESOFITEMS);
		}
		else
			successMsg = "Equipment Transfer";		
		
		if (validateAssetTransaction(assetTransaction, result)) {
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return target;
		}
		
				
		if(validateIssueOrder(assetTransaction, result)){
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return target;
		}

		assetTransaction.setCreatedBy(getCurrentUserName(request));
		
		prepareAuditObject(assetTransaction, request);

		if(type.contains(AssetTransaction.TRANSACTIONTYPE_SALESOFITEMS))
			assetTransactionService.createSalesOfItems(assetTransaction);			
		else
		 assetTransactionService.createStockTransferEquipments(assetTransaction);
		
		setSuccessMessage(getMessageResources("success.create",successMsg ));

		return "redirect:"+CONTEXT_PATH+"/updateStockTransfer/" + assetTransaction.getAssetTransactionId();


	}

	@RequestMapping(value="create",method=RequestMethod.POST)
	public String saveIssueOrder(@ModelAttribute AssetTransaction assetTransaction, BindingResult result,Model model,HttpServletRequest request, HttpSession session) {

		if (validateAssetTransaction(assetTransaction, result)) {	
			List<Location> fromLocations = getTheIssueLocation(session);
			List<Location> tmp = (List<Location>) request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCATION);
			List<Location> toLocations = new ArrayList<Location>();
			toLocations.addAll(tmp);
			toLocations.removeAll(fromLocations);
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return JSP_MAIN_FORM;
		}

		assetTransaction.setCreatedBy(getCurrentUserName(request));
		
		prepareAuditObject(assetTransaction, request);
		
		assetTransactionService.createIssueOrderComponents(assetTransaction);
		
		setSuccessMessage(getMessageResources("success.create","Issue Order " ));

		return "redirect:"+CONTEXT_PATH+"/update/" + assetTransaction.getAssetTransactionId();


	}
	

	@RequestMapping(value={"update/{id}"}, method = RequestMethod.GET)
	public String showUpdateAssetTransaction(@PathVariable Integer id,Model model,HttpServletRequest request, HttpSession session) {

		AssetTransaction assetTransaction = assetTransactionService.getAssetTransaction(id);
		
		if(assetTransaction==null) {
			throw new ResourceNotFoundException("Issue Order " + id);
		}

		model.addAttribute("selectLocations", getTheIssueLocation(session));
		model.addAttribute(assetTransaction);
		
		String type =  assetTransaction.getAssetTransactionType()!=null? (String)assetTransaction.getAssetTransactionType():"";
		
		if(assetTransaction.isIssueOrderComponent())
			return JSP_MAIN_FORM;
		else if (type.contains("SOI"))
			return JSP_STOCK_SALES;
		else
			return JSP_STOCK_TRANSFER;
		
	}

	@RequestMapping(value="update/{id}",method=RequestMethod.POST)
	public String updateAssetTransaction(@PathVariable Integer id,@ModelAttribute AssetTransaction assetTransaction, BindingResult result,Model model,HttpServletRequest request) {

		if (validateAssetTransaction(assetTransaction, result)) {
			return JSP_MAIN_FORM;
		}

		assetTransaction.setModifiedBy(getCurrentUserName(request));
		
		prepareAuditObject(assetTransaction, request);
		
		assetTransactionService.updateAssetTransaction(assetTransaction);
		
		setSuccessMessage(getMessageResources("success.update","Issue Order " ));


		return "redirect:"+CONTEXT_PATH+"/update/" + assetTransaction.getAssetTransactionId();	

	}

	
	@RequestMapping(value={"updateStockTransfer/{id}"}, method = RequestMethod.GET)
	public String showUpdateStockTransfer(@PathVariable Integer id,Model model,HttpServletRequest request) {

		AssetTransaction assetTransaction = assetTransactionService.getAssetTransaction(id);
		
		SystemUser systemUser = systemUserService.getUser(getCurrentUserName(request));
		
		Section section = getCurrentSection(request);
		
		 if(systemUser.isSuperAdmin())
		{	
			model.addAttribute("approvalRole",true);			
		}
		 
		 else
		 {
				if(section!=null)
				{
					Location location = assetTransaction.getToLocation();
					if(location.getSection().getSectionId().intValue()==section.getSectionId())
					{
						model.addAttribute("approvalRole",true);
					}
					else
						model.addAttribute("approvalRole",false);
				}		
				
				else
					model.addAttribute("approvalRole",true);
		}
		 
		 if(assetTransaction==null) {
				throw new ResourceNotFoundException("Issue Order " + id);
			}
		
		String type =  assetTransaction.getAssetTransactionType()!=null? (String)assetTransaction.getAssetTransactionType():"";
		

		model.addAttribute(assetTransaction);
		
		if (type.contains("SOI"))
			return JSP_STOCK_SALES;
		else
		  return JSP_STOCK_TRANSFER;
	}

	@RequestMapping(value="updateStockTransfer/{id}",method=RequestMethod.POST)
	public String updateStockTransfer(@PathVariable Integer id,@ModelAttribute AssetTransaction assetTransaction, BindingResult result,Model model,HttpServletRequest request) {

		
		String type =  assetTransaction.getAssetTransactionType()!=null? (String)assetTransaction.getAssetTransactionType():"";
		String target = JSP_STOCK_TRANSFER;
		String successMsg = "";
		if(type.contains("SOI")){
			target = JSP_STOCK_SALES;
			successMsg = "Sales Of Items";
		}
		else
			successMsg = "Equipment Transfer";	
		
		List<Location> fromLocations = new ArrayList<Location>();
		List<Location> toLocations = new ArrayList<Location>();
		populateLocations(fromLocations,toLocations,assetTransaction,request);
		
		if (validateAssetTransaction(assetTransaction, result)) {
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			
			return target;
		}
		
		
		
		if(validateIssueOrder(assetTransaction, result)){
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return target;
		}


		assetTransaction.setModifiedBy(getCurrentUserName(request));
		
		prepareAuditObject(assetTransaction, request);
		
		assetTransactionService.updateStockTransferEquipments(assetTransaction);
		
		setSuccessMessage(getMessageResources("success.update",successMsg));

		return "redirect:"+CONTEXT_PATH+"/updateStockTransfer/" + assetTransaction.getAssetTransactionId();
		
	}
	
	@RequestMapping(value="approveStockTransfer/{id}",method=RequestMethod.POST)
	public String approveStockTransfer(@PathVariable Integer id,@ModelAttribute AssetTransaction assetTransaction, BindingResult result,Model model,HttpServletRequest request) {

		
		String type =  assetTransaction.getAssetTransactionType()!=null? (String)assetTransaction.getAssetTransactionType():"";
		String target = JSP_STOCK_TRANSFER;
		String successMsg = "";
		if(type.contains("SOI")){
			target = JSP_STOCK_SALES;
			successMsg = "Sales Of Items";
		}
		else
			successMsg = "Equipment Transfer";
		
		List<Location> fromLocations = new ArrayList<Location>();
		List<Location> toLocations = new ArrayList<Location>();
		populateLocations(fromLocations,toLocations,assetTransaction,request);
		
		
		if (validateAssetTransaction(assetTransaction, result)) {
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			
			return target;
		}
		
		
		if(validateIssueOrder(assetTransaction, result)){
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return target;
		}

		assetTransaction.setModifiedBy(getCurrentUserName(request));
		
		assetTransaction.setApprovedBy(getCurrentUserName(request));
		
		prepareAuditObject(assetTransaction, request);
		
		assetTransactionService.approveStockTransferEquipments(assetTransaction);
		
		setSuccessMessage(getMessageResources("success.approve",successMsg ));

		return "redirect:"+CONTEXT_PATH+"/updateStockTransfer/" + assetTransaction.getAssetTransactionId();
		
	}
	
	@RequestMapping(value="createInHouseTransfer",method=RequestMethod.POST)
	public String saveInHouseTransfer(@ModelAttribute AssetTransaction assetTransaction, BindingResult result,Model model,HttpServletRequest request) {

		List<Location> fromLocations = new ArrayList<Location>();
		List<Location> toLocations = new ArrayList<Location>();
		populateLocations(fromLocations,toLocations,assetTransaction,request);
		
		if (validateAssetTransaction(assetTransaction, result)) {	
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return JSP_STOCK_TRANSFER;
		}
		
		
		if(validateIssueOrder(assetTransaction, result)){
			model.addAttribute("fromLocations", fromLocations);
			model.addAttribute("toLocations", toLocations);
			return JSP_STOCK_TRANSFER;
		}


		assetTransaction.setCreatedBy(getCurrentUserName(request));
		assetTransaction.setApprovedBy(getCurrentUserName(request));
		
		prepareAuditObject(assetTransaction, request);

		assetTransactionService.createInHouseTransferEquipments(assetTransaction);
		
		setSuccessMessage(getMessageResources("success.create","In-House Repair" ));

		return "redirect:"+CONTEXT_PATH+"/updateStockTransfer/" + assetTransaction.getAssetTransactionId();


	}
	

	@ModelAttribute(IssueOrderController.SESSION_SEARCH_CRITERIA)
	public SearchCriteria getAssetTransactionSearchCriteria()
	{
		return new SearchCriteria();
	}

	@RequestMapping(value="search")
	public String searchIssueOrder(@ModelAttribute(IssueOrderController.SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria,@ModelAttribute("currentSearchCriteria") SearchCriteria currentSearchCriteria,Model model) {

		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());

		Date dateFrom = null;
		Date dateTo = null;
		
		try{
			if(!checkNullEmpty(searchCriteria.getSearchCriteria("dateFrom"))) {			 
				dateFrom = new SimpleDateFormat(GlobalConstant.DATE_FORMAT_JAVA).parse(searchCriteria.getSearchCriteria("dateFrom").toString());
			}
		}
		catch (ParseException e) {
			searchCriteria.addSearchCriteria("dateFrom", "");
		}
		
		try{
			
			if(!checkNullEmpty(searchCriteria.getSearchCriteria("dateTo"))) {			  
				dateTo= new SimpleDateFormat(GlobalConstant.DATE_FORMAT_JAVA).parse(searchCriteria.getSearchCriteria("dateTo").toString());
			}
		}
		catch (ParseException e) {
			searchCriteria.addSearchCriteria("dateTo", "");
		}	
		
		
		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());
		
		if(!checkNullEmpty(dateFrom) &&  
				!checkNullEmpty(dateTo)) {
		
			searchCriteria.addSearchCriteria("dateModified", new ParameterDateQueryHelper("dateModified",dateFrom, dateTo));
		}
		
		else if(!checkNullEmpty(dateFrom) &&  
				checkNullEmpty(dateTo)){
			searchCriteria.addSearchCriteria("dateModified", new ParameterDateQueryHelper("dateModified",dateFrom, null));
		}		
			
		else if(checkNullEmpty(dateFrom) &&  
				!checkNullEmpty(dateTo)){
			searchCriteria.addSearchCriteria("dateModified", new ParameterDateQueryHelper("dateModified",null, dateTo));
		}
		
		else
		{
			searchCriteria.addSearchCriteria("dateModified", new ParameterDateQueryHelper("dateModified",null, null));
		}
		
		SearchResult searchResult = assetTransactionService.searchIssueOrder(searchCriteria);
		model.addAttribute(searchResult);

		return JSP_MAIN_SEARCH;
	}

	@RequestMapping(value={"delete/{id}"}, method = RequestMethod.GET)
	public String deleteAssetTransaction(@PathVariable Integer id,Model model,HttpServletRequest request) {

		//assetTransactionService.deleteAssetTransaction(id);


		return "redirect:"+CONTEXT_PATH+"/search";
	}
	
	@RequestMapping(value={"print/{id}/{type}"}, method = RequestMethod.GET)
	public void printIssueOrder(@PathVariable Integer id, @PathVariable String type, Model model,HttpServletRequest request,HttpServletResponse response) throws IOException {

		try
		{
			ServletOutputStream servletOutputStream = response.getOutputStream();	
			InputStream reportStream = null;
	
			AssetTransaction assetTransaction = assetTransactionService.getAssetTransaction(id);
		
			HashMap details = new HashMap();

  			String issueOrderType = null;
  			if(StringUtils.equals(AssetTransaction.TRANSACTIONTYPE_ISSUEORDER, assetTransaction.getAssetTransactionType())){
  				issueOrderType = "Issue Component";
  			}else if(StringUtils.equals(AssetTransaction.TRANSACTIONTYPE_EQUIPMENTTRANSFER, assetTransaction.getAssetTransactionType())){
  				issueOrderType = "Equipment Transfer";
  			}else if(StringUtils.equals(AssetTransaction.TRANSACTIONTYPE_FAULTYTRANSFER, assetTransaction.getAssetTransactionType())){
  				issueOrderType = "Faulty Equipment Transfer";
  			}
  			else if(StringUtils.equals(AssetTransaction.TRANSACTIONTYPE_SALESOFITEMS, assetTransaction.getAssetTransactionType())){
  				issueOrderType = "Sales";
  			}
  			
  			else if(StringUtils.equals(AssetTransaction.TRANSACTIONTYPE_INHOUSETRANSFER, assetTransaction.getAssetTransactionType())){
  				issueOrderType = "In-House Repair";
  			}
  			
  			String issueOrderDate = "";
  			
			if(StringUtils.equals(AssetModel.ASSETTYPE_EQUIPMENT, type)){
				if(assetTransaction.getDateCreated() != null){
					issueOrderDate = DateFormatUtils.format(assetTransaction.getDateCreated(), GlobalConstant.DATE_FORMAT_JAVA);
				}
			}else{
				if(assetTransaction.getApprovedDate() != null){
					issueOrderDate = DateFormatUtils.format(assetTransaction.getApprovedDate(), GlobalConstant.DATE_FORMAT_JAVA);
				}
  				
  			}
  			
			details.put("issueOrderType", issueOrderType);
			details.put("fromLocation", assetTransaction.getFromLocation() != null ? assetTransaction.getFromLocation().getLocationName() : "");
			details.put("toLocation", assetTransaction.getToLocation() != null ? assetTransaction.getToLocation().getLocationName() : "");
			details.put("companyCode", assetTransaction.getCompanyCode());
			details.put("toCompanyCode", assetTransaction.getToCompanyCode());
			details.put("issueOrderCode", assetTransaction.getAssetTransactionCode());
			details.put("issueOrderDate", issueOrderDate);
			details.put("issueOrderStatus", assetTransaction.getAssetTransactionStatus());
			details.put("issueOrderStatus", assetTransaction.getAssetTransactionStatus());

			List<AssetTransactionItem> list = assetTransaction.getAssetTransactionItems();			
			int totalItems = list!=null? list.size():0;
			details.put("totalItems", totalItems+"");
			
			if(StringUtils.equals(AssetModel.ASSETTYPE_EQUIPMENT, type)){
				
				if(issueOrderType.equalsIgnoreCase("sales"))
					reportStream =getClass().getClassLoader().getResourceAsStream("report/IssueOrderSalesEquip.jasper");
				
				else if(StringUtils.equals(AssetTransaction.TRANSACTIONTYPE_INHOUSETRANSFER, assetTransaction.getAssetTransactionType()))
					reportStream =getClass().getClassLoader().getResourceAsStream("report/InHouseTransfer.jasper");
				
				else
					reportStream =getClass().getClassLoader().getResourceAsStream("report/IssueOrderEquip.jasper");	
				JasperRunManager.runReportToPdfStream(reportStream,
						servletOutputStream,
						details,
						new JRBeanCollectionDataSource(list));
			}else{
				reportStream =getClass().getClassLoader().getResourceAsStream("report/IssueOrderComp.jasper");	
				 JasperRunManager.runReportToPdfStream(reportStream,
						 servletOutputStream,
							details,
							new JRBeanCollectionDataSource(list));
			}
			response.setContentType("application/pdf");
			servletOutputStream.flush();
			servletOutputStream.close();
		}
		catch (JRException e)
		{
			logger.error(CommonUtil.getStackTrace(e));
			// display stack trace in the browser
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/plain");
			response.getOutputStream().print(stringWriter.toString());
		}

	}


	private boolean validateAssetTransaction(AssetTransaction assetTransaction,BindingResult result)
	{
		if(assetTransaction.getAccessDepartment()!=null && assetTransaction.getAccessDepartment().getDepartmentId()==null)
			assetTransaction.setAccessDepartment(null);
		
		assetTransaction.getAssetTransactionItems();
		
		if(assetTransaction.isIssueOrderComponent())
		{
			Location location = assetTransaction.getFromLocation();
			List<AssetTransactionItem> assetTransactionItems= assetTransaction.getAssetTransactionItems();
			SearchCriteria searchCriteria = new SearchCriteria();
			if(CollectionUtils.isNotEmpty(assetTransactionItems))
			{
				int idx=1;
				for(int i=0;i<assetTransactionItems.size();i++)
				{
					AssetTransactionItem assetTransactionItem  = assetTransactionItems.get(i);
					
					if(assetTransactionItem.isDeleted())continue;
					if(assetTransactionItem.getAssetTransactionQuantity()==null) continue;
					
					AssetModel assetModel = assetTransactionItem.getAssetModel();
					
					searchCriteria.addSearchCriteria("assetModelId", assetModel.getAssetModelId());
					searchCriteria.addSearchCriteria("locationId", location.getLocationId());
					searchCriteria.addSearchCriteria("companyCode", assetTransaction.getCompanyCode());
					List<AssetComponent> list = assetModelService.findAssetComponents(searchCriteria);
					AssetComponent tmp = null;
					if(CollectionUtils.isNotEmpty(list)){
						tmp = list.get(0);
						if(tmp.getQuantity() < assetTransactionItem.getAssetTransactionQuantity()){
							result.reject("error.issueOrder.exceed", new String[]{"in row "+(idx),String.valueOf(tmp.getQuantity())}, "");
						}
					}else{
						result.reject("error.issueOrder.exceed", new String[]{"in row "+(idx),"0"}, "");
					}
					idx++;
					
				}
			}
		}
		
		
		validator.validate(assetTransaction, result);
		
		return result.hasErrors();
	}
	
	private void prepareAuditObject(AssetTransaction assetTransaction, HttpServletRequest request){
		/* audit start */
		Location fromLoc = findLocation(request, assetTransaction.getFromLocation().getLocationId());
		assetTransaction.setFromLocation(fromLoc);
		
		if(assetTransaction.getToLocation()!=null){
			Location toLoc = findLocation(request, assetTransaction.getToLocation().getLocationId());
			assetTransaction.setToLocation(toLoc);
		}
		List<AssetTransactionItem> list = assetTransaction.getAssetTransactionItems();
		if(CollectionUtils.isNotEmpty(list)){
			for(AssetTransactionItem detail : list){
				if(detail.getAssetModel() != null && !detail.isDeleted()){
					Integer assetModelId = detail.getAssetModel().getAssetModelId();
					AssetModel tmp  = findAssetModel(request, assetModelId);
					detail.setAssetModel(tmp);
				}
			}
		}
		/* audit end */	
	}
	
	private List<Location> getTheIssueLocation(HttpSession session){
		SearchCriteria searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);  
		searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_COMPONENT_ISSUE_MAIN_LOCATION);
		SystemCodeType systemCodeType = systemCodeService.findSystemCodeType(searchCriteria);
		List<Location> list = (List<Location>)session.getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCATION);
		List<Location> result = new ArrayList<Location>();
    	if(CollectionUtils.isNotEmpty(list)){
    		for(Location loc : list){
    			if(StringUtils.equals(loc.getLocationCode(), systemCodeType.getSystemCodeTypeValue())){
    				result.add(loc);
    			}
    		}
    	}
    	return result;
	}

	private boolean validateIssueOrder(AssetTransaction assetTransaction,BindingResult result)
	{
		List<String> serialNos = assetTransactionService.isAvaliable(assetTransaction);
		if(CollectionUtils.isNotEmpty(serialNos)){
			for (String serialNo : serialNos) {
				result.reject("error.issueOrder.used", new String[]{serialNo}, "");
			}
		}
		return result.hasErrors();
	}
	
	private void populateLocations(List<Location> fromLocations,List<Location> toLocations,AssetTransaction assetTransaction,HttpServletRequest request){

		if(assetTransaction.isFaultyEquipmentTransfer() || assetTransaction.isInHouseTransfer()) {
			//find the WORKORDER_FAULT_LOCATION value
			SearchCriteria searchCriteria = new SearchCriteria();
			searchCriteria.addSearchCriteria("active", true);  
			searchCriteria.addSearchCriteria("systemCodeTypeCode", GlobalConstant.SYSTEM_CODE_TYPE_REPAIR_TRANSFER_LOCATION);
			SystemCodeType systemCodeType = systemCodeService.findSystemCodeType(searchCriteria);
			String [] ICWS = StringUtils.split(systemCodeType.getSystemCodeTypeValue(), ",") ;
	
			//make the in query
			InQueryHelper helper = new InQueryHelper("locationCode", Arrays.asList(ICWS));
			searchCriteria.addSearchCriteria("active", true);  
			searchCriteria.addSearchCriteria("locationCode", helper);
			fromLocations.addAll(locationService.searchLocationCriteria(searchCriteria));
			toLocations.addAll(fromLocations);
		}else{
			Section section = getCurrentSection(request);
			if(section==null) {
				fromLocations.addAll((List<Location>)request.getSession().getServletContext().getAttribute(GlobalConstant.GLOBAL_LOCATION));
				toLocations.addAll(fromLocations);
			}
			else
			{
				SearchCriteria searchCriteria = new SearchCriteria();
				searchCriteria.addSearchCriteria("sectionId", section.getSectionId());
				fromLocations.addAll(locationService.searchLocationCriteria(searchCriteria));
				searchCriteria = new SearchCriteria();
				toLocations.addAll(locationService.searchLocationCriteria(searchCriteria));
			}
		}
		
	}
}
